from os import popen
import subprocess
from sys import exit, argv
from datetime import datetime
import re

def parse(key, min_id=0, sudo_key='sudo', ts=None):
    '''In addition to a normal auditing rule,
    another auditing rule recording who runs sudo
    should also be in use. This parser will find 
    out who "actually" does operations whenever 
    possible.
      key:      auditing key for normal events
      min_id:   only process events having id > min_id
      sudo_key: auditing key for sudo events
      ts:       only process events having larger timestamp
    '''
    ts = '' if not ts else '-ts %s' % datetime.fromtimestamp(ts).strftime('%m/%d/%Y %H:%M:%S.%f')
    cmd = 'ausearch -k %s -m PATH %s' % (key, ts)
    raws = popen(cmd).read().split('----\n')
    raws.pop(0)
    records = []
    questions = []
    for r in raws:
        try:
            record = {}
            ts_and_id = re.search('(?<=audit\\().*?(?=\\))', r).group(0).split(':')
            record['ts'] = float(ts_and_id[0])
            record['id'] = int(ts_and_id[1])
            if record['id'] <= min_id:
                continue
            record['path'] = '%s/%s' % (re.search('(?<=cwd=").*?(?=")', r).group(0), re.search('(?<=name=").*?(?=")', r).group(0))
            record['exe'] = re.search('(?<=exe=").*?(?=")', r).group(0)
            record['syscall'] = int(re.search('(?<=syscall=)\d*', r).group(0))
            record['uid'] = int(re.search('(?<=\\ uid=)\d*', r).group(0))
            if record['uid'] == 0:
                sudo_rec = popen('ausearch -k %s -p %s' % (sudo_key, re.search('(?<=ppid=)\d*', r).group(0))).read()
                try:
                    record['uid'] = int(re.search('(?<=\\ uid=)\\d*', sudo_rec).group(0))
                except AttributeError:
                    # This will happen when it is indeed root that takes actions
                    pass
            records.append(record)
        except:
            questions.append(r)
    return records

if __name__ == '__main__':
    records = parse('letsrock', ts=0, min_id=0)
    for r in records:
        print r
